Skip to content

feat(agentic-server): carry invocation/job/attempt/run linkage into InferenceEntry - #1812

Merged
pyramation merged 2 commits into
mainfrom
feat/agentic-server-inference-task-linkage
Sep 7, 2026
Merged

feat(agentic-server): carry invocation/job/attempt/run linkage into InferenceEntry#1812
pyramation merged 2 commits into
mainfrom
feat/agentic-server-inference-task-linkage

Conversation

@pyramation

@pyramation pyramation commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Companion to constructive-db Phase 3 of the billing plan (constructive-planning#1985): inference is COGS attributed to the task the customer paid for, never a customer meter of its own. For that join to exist, both ends of the gateway have to carry which task each model call belongs to.

Gateway (agentic-server)

  • InferenceEntry gains invocationId?, jobId?, attempt?, runId?; new InferenceAttribution = Pick<InferenceEntry, 'databaseId'|'entityId'|'actorId'|…linkage> exported.
  • readAttribution(req) reads X-Database-Id / X-Entity-Id / X-Actor-Id / X-Invocation-Id / X-Job-Id / X-Attempt / X-Run-Id once per request; every sink.logInference({...}) call (chat ok/error/stream, embed ok/error, /v1/usage) spreads it, so no sink path can drop linkage. X-Attempt must be ^\d+$ or is dropped.
  • Trust boundary: the four correlation headers join IDENTITY_HEADERS, so a public (isPublic: true) server strips them exactly like identity — an external client cannot pin its usage onto someone else's invocation.

Client (@agentic-kit/metering + @agentic-kit/pi) — the producer side the reviewer flagged as inert

  • MeteredIdentity gains the same four optional fields; buildIdentityHeaders emits them (throws up front on a non-digit jobId or non-integer/negative attempt, same posture as the existing databaseId check). Both the gateway lane and the self-report lane (reporter.ts) go through this one function.
  • composeRun threads its runId into the metering identity: identity: { runId: options.runId, ...identity } — so every pi run now sends X-Run-Id, while a host may still pin it explicitly. Hosts that dispatch from a platform invocation pass invocationId/jobId/attempt on the identity.

Wire format is unchanged for callers that don't send the headers (all fields optional). The constructive-db runtimes send X-Invocation-Id/X-Job-Id/X-Attempt from the job frame.

Tests: agentic-server gateway 22/22, metering 38/38, pi 62/62 — linkage forwarded end to end, malformed/absent linkage stays undefined or is refused client-side, public strip.

Link to Devin session: https://app.devin.ai/sessions/bc06c04115054722b1913a1bcfd99256
Open in Devin Desktop: https://app.devin.ai/desktop/session/bc06c04115054722b1913a1bcfd99256?variant=devin
Requested by: @pyramation

…nferenceEntry; strip correlation headers on public servers
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@tenki-reviewer

tenki-reviewer Bot commented Sep 7, 2026

Copy link
Copy Markdown

Review complete. 🟡 1 medium

💬 Inline comments (1)

  • 🟡 Correlation headers never forwarded by the metering runtimerouter.ts:71

The agentic-server gateway now reads task-correlation headers (X-Invocation-Id, X-Job-Id, X-Attempt, X-Run-Id) in readAttribution and spreads them into every logInference entry, adds them to the identity-header strip list, exports a new InferenceAttribution type, and covers forwarding plus malformed-X-Attempt behavior with tests. However, the in-repo producer (@agentic-kit/metering) that sends traffic to this gateway never emits these headers, so the correlation fields are always undefined in real traffic and the PR's goal of joining tokens to a task is not realized end-to-end.

Files Change
agentic/agentic-server/src/router.ts, src/server.ts, src/types.ts, src/index.ts Add readAttribution header parsing, strip correlation headers from identity headers, and export the new attribution type.
agentic/agentic-server/tests/gateway.test.ts Add tests for correlation-header forwarding and malformed X-Attempt handling.

Reviewed commit: ae65bd8

@tenki-reviewer tenki-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adds task-correlation header reading to the agentic-server gateway so inference entries can be attributed to a task, but the metering producer never forwards those headers, leaving the feature inert end-to-end.

Key findings

  • 🟡 Correlation headers never forwarded by the metering runtimerouter.ts:71

Comment thread agentic/agentic-server/src/router.ts
…tion-Id/X-Job-Id/X-Attempt on MeteredIdentity, X-Run-Id threaded from composeRun
@pyramation
pyramation merged commit acf434e into main Sep 7, 2026
20 checks passed
@pyramation
pyramation deleted the feat/agentic-server-inference-task-linkage branch September 7, 2026 07:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant